﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CommandEditor;
using CommandLists.Model;
using IDE;
using CommandLists.Properties;
using DomainModelEditor;
using CommonClasses;
using CommonClasses.Services;
using CommonClasses.Utility;
using CommonClasses.Logger;
using Descriptions_DomainModel.Model;
using Descriptions_PinsDescription.Model;

using Axiom;
using Axiom.Core;
using Axiom.Graphics;
using Axiom.Configuration;
using Axiom.Math;
using Axiom.Overlays;
using Axiom.Input;
using Axiom.Animating;

using VisualDM.Model;
using Visualizator;

using CommandLists.Controls;
using PinsDescriptionEditor;
using System.IO;
using Eco.Services;
using Descriptions_DomainModelLoader;
using RunTime;
using ModellingModule;

namespace CommandLists
{
    public partial class CommandListsForm : Form
    {

        #region public

        /// <summary>
        /// Обработчик события изменения пути загруженной программы
        /// </summary>
        /// <param name="NewFileName">новый путь</param>
        public delegate void FileNameChangedHandler(string newFileName);

        /// <summary>
        /// Событие: изменился путь до загруженной программы
        /// </summary>
        public event FileNameChangedHandler FileNameChangedEvent;

        /// <summary>
        /// Вызвать событие изменения имени проекта
        /// </summary>
        /// <param name="newFileName"></param>
        public void FileNameChanged(string newFileName)
        {
            if (FileNameChangedEvent != null)
                FileNameChangedEvent(newFileName);
        }

        private string fileNameF = string.Empty;

        /// <summary>
        /// Путь до файла с текущей программой
        /// </summary>
        public string FileName
        {
            get
            {
                return fileNameF;
            }
            set
            {
                var OldName = FileName;

                fileNameF = PathUtility.MakePathLocal(value, Locality.ExeFile);

                if (OldName != fileNameF)
                {
                    //this.Text = "Списки команд - [" + Path.GetFileNameWithoutExtension(FileName) + "]";
                    FileNameChanged(fileNameF);
                }
            }
        }
        #endregion

        #region private

        private ILoggingManagement loggingManagement;
        private ILogger logger;
        private IDEEcoSpace ecoSpace;

        private KeyPressMessageFilter keyFilter;
        private bool IsRealBenchConnected = false;

        /// <summary>
        /// Выбранный тип оборудования
        /// </summary>
        private BenchType benchType = BenchType.Virtual;

        /// <summary>
        /// Список модулей для связи с устройствами через порты
        /// </summary>
        /// <remarks> список нужен лишь для того, чтобы потом их отключить</remarks>
        private List<IModule> modules_real = new List<IModule>();

        /// <summary>
        /// Супервизор работы с виртуальным обордованием
        /// </summary>
        private ModellingSupervisor.ModellingSupervisor modellingSupervisor;

        /// <summary>
        /// Модуль для работы с виртуальным обордованием
        /// </summary>
        private ModellingModule.ModellingModule modellingModule;

        /// <summary>
        /// Картинки play и pause
        /// </summary>
        /// <remarks>
        /// [0] - play
        /// [1] - pause
        /// </remarks>
        private List<Image> playPauseImages = new List<Image>();
        #endregion

        #region Execute
        //настройки формы в зависимости от режима исполнения
        private Dictionary<BenchType, FormSetting> modeToFormSettings = new Dictionary<BenchType, FormSetting>();

        //диспетчер, пересылающий сигналы на управляющие сборки
        private SupervisorDispatcher supervisorDispatcher;

        //диспетчер, пересылающий сигналы на подключения
        private ConnectionDispatcher connectionDispatcher;

        //таблица пинов, которая регистрируется в луа
        private VirtualPinTable pinTable;

        /// <summary>
        /// Режим выполненения
        /// </summary>
        private enum Mode
        {
            Play,
            Stop,
            Pause
        }

        /// <summary>
        /// Режим выполненения
        /// </summary>
        private Mode mode = Mode.Stop;

        /// <summary>
        /// Окно, показываемое при компиляции
        /// </summary>
        private CompilationForm compilationForm = new CompilationForm();
        #endregion

        #region Modelling
        private Visualizator.Visualizator VisualManager;
        #endregion

        public CommandListsForm(IDEEcoSpace ecospace, ILoggingManagement loggingmanagment, Visualizator.Visualizator visualisationManager)
        {
            loggingManagement = loggingmanagment;
            logger = loggingManagement.GetLogger("CommandListsLogger");
            this.ecoSpace = ecospace;
            this.VisualManager = visualisationManager;

            InitializeComponent();

            InitializeMessageFilter();
            InitializeCommandLists();
            InitializeFormSettings();

            LoadDeviceDescriptions();

            var pinsDescriptionTable = ecoSpace.Ocl.Evaluate("PinsDescriptionTable.allInstances->first").AsObject as PinsDescriptionTable;
            var domainModel = ecoSpace.Ocl.Evaluate("DomainModel.allinstances->first").AsObject as DomainModel;
            var vdm = ecoSpace.Ocl.Evaluate("VisualDomainModel.allinstances->first").AsObject as VisualDomainModel;

            connectionDispatcher = new ConnectionDispatcher();
            supervisorDispatcher = new SupervisorDispatcher();

            pinTable = new VirtualPinTable(supervisorDispatcher, pinsDescriptionTable, loggingManagement);
            ecoSpace.GetEcoService<IVirtualMachineService>().RegisterObject("vipins", pinTable);

            modellingSupervisor = new ModellingSupervisor.ModellingSupervisor(domainModel, vdm, pinTable, loggingManagement);

            modellingModule = new ModellingModule.ModellingModule(ecospace);

            // Требуются: domainModel
            supervisorDispatcher.AddSupervisor(new MockConnection("MockSupervisor"));
            supervisorDispatcher.AddSupervisorsRange(new ManagingAssembliesLoader(ecoSpace, logger, connectionDispatcher)
                                 .GetAssemblies(domainModel));
            supervisorDispatcher.AddSupervisor(modellingSupervisor);

            ConnectToVirtualBench();

            InitializeVisualization();

            ecoSpace.GetEcoService<ISystemTimer>().Interval = 40;
            ecoSpace.GetEcoService<IVirtualMachineService>().OnAllCoroutineDead += new MethodInvoker(CommandListsForm_OnProgramEnded);
            commandListsControl.OnProgramEnded += new MethodInvoker(commandListsControl_OnProgramEnded);
            commandListsControl.OnModeChanged += new CommandListsControl.ModeChangedHandler(commandListsControl_OnModeChanged);
            commandListsControl.OnInterpreterBlockStarted += new EventHandler(commandListsControl_OnInterpreterBlockStarted);
            commandListsControl.OnInterpreterBlockEnded += new EventHandler(commandListsControl_OnInterpreterBlockEnded);

            playPauseImages.Add(Properties.Resources.Play);
            playPauseImages.Add(Properties.Resources.Pause);

            PlayPauseAllToolStripMenuItem.Image = playPauseImages[0];
            StopStripMenuItem.Enabled = false;
        }

        /// <summary>
        /// При начале выполнения команды в режиме интерпретации (такта)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void commandListsControl_OnInterpreterBlockEnded(object sender, EventArgs e)
        {
            StopStripMenuItem.Enabled = false;
            //PlayPauseAllToolStripMenuItem.Enabled = true;
        }

        /// <summary>
        /// ПРи конце выполнения команды в режиме интерпретации (такта)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void commandListsControl_OnInterpreterBlockStarted(object sender, EventArgs e)
        {
            StopStripMenuItem.Enabled = true;
            //PlayPauseAllToolStripMenuItem.Enabled = false;
        }

        /// <summary>
        /// Когда изменяют режим на отладку или редактирование
        /// </summary>
        /// <param name="mode"></param>
        private void commandListsControl_OnModeChanged(CommandListsExecuteMode mode)
        {
            if (mode == CommandListsExecuteMode.Interpretation)
            {
                ModeToolStripMenuItem.Enabled = false;
                PlayPauseAllToolStripMenuItem.Enabled = false;
                verifyToolStripMenuItem.Enabled = false;
                //ecoSpace.GetEcoService<IVirtualMachineService>().Begin();
                modellingSupervisor.Begin();               
            }
            else if (mode == CommandListsExecuteMode.AllInOnce)
            {
                OnStop();
                PlayPauseAllToolStripMenuItem.Enabled = true;
                verifyToolStripMenuItem.Enabled = true;
                /*
                ModeToolStripMenuItem.Enabled = true;
                PlayPauseAllToolStripMenuItem.Enabled = true;
                //ecoSpace.GetEcoService<IVirtualMachineService>().End();
                modellingSupervisor.End();
                 */
            }            
        }


        /// <summary>
        /// Когда в СК закончилась программа
        /// </summary>
        private void commandListsControl_OnProgramEnded()
        {
            CommandListsForm_OnProgramEnded();
        }

        /// <summary>
        /// При закрытии окна
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">FormClosingEventArgs</param>
        private void CommandListsForm_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        //protected override void WndProc(ref Message m)
        //{
        //    //if (m.Msg == WM_LBUTTONDOWN)
        //    //{
        //        Console.WriteLine("Form: " + m.ToString());
        //    //}
        //    base.WndProc(ref m);
        //}

        #region Initialization

        private void InitializeMessageFilter()
        {
            keyFilter = new KeyPressMessageFilter();
            Application.AddMessageFilter(keyFilter);
        }

        private void InitializeFormSettings()
        {
            modeToFormSettings.Add(BenchType.Virtual, new FormSetting
                {
                    IsModellingCollapsed = false,
                    ModeStripText = "Установка: виртуальная"
                });

            modeToFormSettings.Add(BenchType.Real, new FormSetting
            {
                IsModellingCollapsed = true,
                ModeStripText = "Установка: реальная"
            });
        }

        private void InitializeCommandLists()
        {
            commandListsControl.Initialize(ecoSpace, loggingManagement.GetLogger("CommandListsLogger"));

            foreach (var item in commandListsControl.GetMenus())
                menuStrip1.Items.Insert(1, item);

            keyFilter.Subscribe(new KeyPressEventHandler(commandListsControl.HandleKeyPress));
        }

        private void LoadDeviceDescriptions()
        {
            var domainModel = ecoSpace.Ocl.Evaluate("DomainModel.allInstances->first").AsObject as DomainModel;

            //var dmNameNoExt = Path.GetDirectoryName(fileName) + "\\" + Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName));

            commandListsControl.LoadConfigFromFile(Path.GetDirectoryName(domainModel.PathNoExt) + "\\config_CL\\cfg.main.clcfg");

            ecoSpace.GetEcoService<ITranslatorService>().Initialize(domainModel);
        }

        private void InitializeDispatchers()
        {


        }

        private void InitializeVisualization()
        {
            /*
            if (VisualManager == null)
            {
                var vdm = ecoSpace.Ocl.Evaluate("VisualDomainModel.allInstances->first").AsObject as VisualDomainModel;
                VisualManager = new Visualizator.Visualizator(ecoSpace, this, vdm);

                CameraSceneObject cam = new CameraSceneObject(ecoSpace) { Name = "Main_Camera", ID = 0x01 };
                cam.DefaultPosition.Vector = new Vector3(64.28306f, 96.96927f, 177.968857f);
                cam.DefaultLookAt.Vector = new Vector3(0, 0, 0);
                //            cam.DefaultDirection.Vector = new Vector3(-0.4318532f, -0.5039893f, -0.7479947f);

                DirectionalLightSceneObject l = new DirectionalLightSceneObject(ecoSpace) { Name = "Main_Light", ID = 0x02 };
                l.Color.Color = new ColorEx(0.5f, 0.5f, 0.5f);
                l.DefaultPosition.Vector = new Vector3(500, 500, 500);
                l.Direction.Vector = new Vector3(-1, -1, -1);
                l.Specular.Color = new ColorEx(1.0f, 1.0f, 1.0f);
                l.Diffuse.Color = new ColorEx(1.0f, 1.0f, 0.8f);
                VisualManager.AddSceneObject(l);

                VisualManager.AddRenderWindow(visualizationTarget, cam);
                vdm.Initialize(VisualManager.sceneManager);

                VisualManager.StartRender();
            
            }
            */
            /*
            else 
               ecoSpace.Ocl.Evaluate("IVisualizationService.allInstances->First").AsObject as Visualizator.Visualizator;*/


            keyFilter.Subscribe(new KeyPressEventHandler(VisualManager.HandleKeyPress));

            ecoSpace.GetEcoService<ISystemTimer>().Subscribe(OnTick);

            visualizationTimer.Tick += new EventHandler(OnVisualizationTick);
            visualizationTimer.Enabled = true;
        }


        /// <summary>
        /// Освободить подключение
        /// </summary>
        private void DeInitializeConnections()
        {
            var timer = ecoSpace.GetEcoService<ISystemTimer>();
            connectionDispatcher.RemoveAllConnections();
            foreach (var mod in modules_real)
            {
                timer.DetachSubcribtion(mod.OnTick);                
                mod.Dispose();
            }
            modules_real.Clear();
            modellingSupervisor.Dispose();
            modellingModule.Dispose();
        }

        #endregion

        #region Mode

        private void ModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            benchType = benchType == BenchType.Virtual ? BenchType.Real : BenchType.Virtual;

            //применяем настройки из modeSettings
            ModeToolStripMenuItem.Text = modeToFormSettings[benchType].ModeStripText;

            //сворачиваем\разворачиваем моделирование
            MainSplitContainer.Panel2Collapsed = modeToFormSettings[benchType].IsModellingCollapsed;

            if (benchType == BenchType.Virtual)
                ConnectToVirtualBench();
            commandListsControl.SetMenuItemsEnableByBenchType(benchType);
        }

        /// <summary>
        /// Установить подключение к реальной установке (составить список подключений, т.е. модулей)
        /// </summary>
        private void ConnectToRealBench()
        {
            if (IsRealBenchConnected)
                DeInitializeConnections();

            var pinsDescriptionTable = ecoSpace.Ocl.Evaluate("PinsDescriptionTable.allInstances->first").AsObject as PinsDescriptionTable;
            var timer = ecoSpace.GetEcoService<ISystemTimer>();
            connectionDispatcher.RemoveAllConnections();
            connectionDispatcher.AddConnection(new MockConnection("MockModule"));
            connectionDispatcher.AddConnection(modellingModule);
            modellingSupervisor.SetMode(false);

            #region Инициализируем реальные модули (Ke + Stepper)
            try
            {
                foreach (var KEetalon in pinsDescriptionTable.Etalons)
                {
                    var KE = new KEUSBModule.KEUSBModule(pinsDescriptionTable, KEetalon.Descriptor);
                    modules_real.Add(KE);
                    timer.Subscribe(KE.OnTick);
                    connectionDispatcher.AddConnection(KE);
                }

                /*
                var stepperModule = new StepperModule.StepperModule(pinsDescriptionTable, 47);
                modules_real.Add(stepperModule);
                timer.Subscribe(stepperModule.OnTick);
                connectionDispatcher.AddConnection(stepperModule);
                 */ 

                IsRealBenchConnected = true;
            }
            catch (KEUSB24AAbsentException kex)
            {
                IsRealBenchConnected = false;
                OnStop();
                return;
            }
            #endregion
        }

        /// <summary>
        /// Установить подключение к виртуальной установке (составить список подключений, т.е. модулей)
        /// </summary>
        private void ConnectToVirtualBench()
        {
            var pinsDescriptionTable = ecoSpace.Ocl.Evaluate("PinsDescriptionTable.allInstances->first").AsObject as PinsDescriptionTable;
            var timer = ecoSpace.GetEcoService<ISystemTimer>();
            connectionDispatcher.RemoveAllConnections();
            connectionDispatcher.AddConnection(new MockConnection("MockModule"));
            connectionDispatcher.AddConnection(modellingModule);
            modellingSupervisor.SetMode(true);
        }

        #endregion

        #region Execute

        private void CommandListsForm_OnProgramEnded()
        {
            if ((mode != Mode.Stop) && (commandListsControl.Mode == CommandListsExecuteMode.AllInOnce))
            {
                OnStop();
            }
        }

        /// <summary>
        /// Действия при полной остановке программы
        /// </summary>
        private void OnStop()
        {
            mode = Mode.Stop;
            PlayPauseAllToolStripMenuItem.Text = "Запустить";
            PlayPauseAllToolStripMenuItem.Image = playPauseImages[0];
            verifyToolStripMenuItem.Enabled = true;
            StopStripMenuItem.Enabled = false;
            FileStripMenuItem.Enabled = ModeToolStripMenuItem.Enabled = FileStripMenuItem.DropDownItems[0].Enabled = FileStripMenuItem.DropDownItems[1].Enabled = true;            
            ecoSpace.GetEcoService<IVirtualMachineService>().End();
            commandListsControl.Stop();
            modellingSupervisor.End();
            connectionDispatcher.FlushPins();
            supervisorDispatcher.FlushPins();
            VisualManager.ResetToInitPositions();
            if (benchType == BenchType.Real)
                DeInitializeConnections();
            commandListsControl.SetDebugMode(false);
            commandListsControl.SetMenuItemsEnableByBenchType(benchType);
        }

        /// <summary>
        /// Обработчик нажатия на кнопку верификации
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void verifyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            compilationForm.btnOK.Hide();
            compilationForm.tbStatus.Clear();
            compilationForm.Show();            
            
            var report = commandListsControl.CompileAll(compilationForm, true);            

            compilationForm.Update();
            Application.DoEvents();
            compilationForm.Hide();
            compilationForm.btnOK.Text = "OK";
            compilationForm.btnOK.Show();
            compilationForm.ShowDialog();

            if (report.Errors.Count > 0)
            {                
                MessageBox.Show(
                    report.Errors.Aggregate("", (acc, er) => acc + (acc != "" ? "\n" : "") + er.Message), "Внимание, ошибки!",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }            
        }

        private void RunAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (mode == Mode.Stop)
            {
                // Play
                modellingSupervisor.End();

                compilationForm.btnOK.Hide();
                compilationForm.tbStatus.Clear();
                compilationForm.Show();

                var report = commandListsControl.CompileAll(compilationForm, false/*benchType == BenchType.Real*/);

                if (report.Errors.Count > 0)
                {
                    compilationForm.tbStatus.Text += "\r\nЗапуск программы невозможен";
                    compilationForm.Update();
                    Application.DoEvents();
                    compilationForm.Hide();
                    compilationForm.btnOK.Text = "OK";
                    compilationForm.btnOK.Show();
                    compilationForm.ShowDialog();

                    MessageBox.Show(
                        report.Errors.Aggregate("", (acc, er) => acc + (acc != "" ? "\n" : "") + er.Message), "Внимание, ошибки!",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                    return;
                }

                if (benchType == BenchType.Real)
                {
                    ConnectToRealBench();
                    if ((!IsRealBenchConnected))
                    {
                        compilationForm.tbStatus.Text += "\r\nОтсутствует подключение к установке!\r\nЗапуск программы невозможен";
                        compilationForm.Update();
                        Application.DoEvents();
                        compilationForm.Hide();
                        compilationForm.btnOK.Text = "OK";
                        compilationForm.btnOK.Show();
                        compilationForm.ShowDialog();
                        compilationForm.Hide();
                        MessageBox.Show("Проверьте питание блока управления и наличие соединения по USB", "Ошибка подключения", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        DeInitializeConnections();
                        return;
                    }
                    else
                    {
                        Cursor.Current = Cursors.WaitCursor;
                        compilationForm.tbStatus.Text += "\r\nПодготовка к запуску...";
                        compilationForm.Update();
                        Application.DoEvents();
                        compilationForm.Hide();
                        compilationForm.btnOK.Text = "Далее";
                        compilationForm.btnOK.Show();                        
                        compilationForm.tbStatus.Text += "\r\nПрограмма к запуску готова";
                        Cursor.Current = Cursors.Default;
                        compilationForm.ShowDialog();

                        if (
                        MessageBox.Show(
@"Внимание, производится запуск техпроцесса на реальном оборудовании!

Убедитесь, что:
1) Давление на установку подано;
2) Устройство управления включено;
<...>", "Предупреждение", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)
                             != DialogResult.OK)
                        {
                            StopStripMenuItem_Click(null, null);
                            return;
                        }
                        else // Поехали!
                        {
                            foreach (var mod in modules_real)
                            {
                                mod.Initialize();
                            }
                        }
                    }
                }
                else
                {
                    Cursor.Current = Cursors.WaitCursor;
                    compilationForm.tbStatus.Text += "\r\nПодготовка к запуску...";
                    compilationForm.Update();
                    Application.DoEvents();
                    compilationForm.Hide();
                    compilationForm.btnOK.Text = "Пуск";
                    compilationForm.btnOK.Show();
                    compilationForm.tbStatus.Text += "\r\nПрограмма к моделированию готова";
                    Cursor.Current = Cursors.Default;
                    compilationForm.ShowDialog();
                }                

                commandListsControl.ExecuteLastCompiled();
                modellingSupervisor.Begin();

                verifyToolStripMenuItem.Enabled = false;
                PlayPauseAllToolStripMenuItem.Text = "Приостановить";
                PlayPauseAllToolStripMenuItem.Image = playPauseImages[1];
                FileStripMenuItem.Enabled = ModeToolStripMenuItem.Enabled = FileStripMenuItem.DropDownItems[0].Enabled = FileStripMenuItem.DropDownItems[1].Enabled = false;
                //ModeToolStripMenuItem.ForeColor = Color.Black;
                StopStripMenuItem.Enabled = true;
                mode = Mode.Play;
            }
            else if (mode == Mode.Play)
            {
                PlayPauseAllToolStripMenuItem.Image = playPauseImages[0];
                PlayPauseAllToolStripMenuItem.Text = "Возобновить";
                ecoSpace.GetEcoService<ISystemTimer>().Enabled = false;
                mode = Mode.Pause;
            }
            else if (mode == Mode.Pause)
            {
                PlayPauseAllToolStripMenuItem.Text = "Приостановить";
                PlayPauseAllToolStripMenuItem.Image = playPauseImages[1];
                ecoSpace.GetEcoService<ISystemTimer>().Enabled = true;
                mode = Mode.Play;
            }
        }

        #endregion

        #region Event handlers

        private void NewStripMenuItem_Click_1(object sender, EventArgs e)
        {
            New();
        }

        private void SaveStripMenuItem_Click(object sender, EventArgs e)
        {
            /*
             * Old version - saving the program not saving the project
             *
             
            if (FileName != string.Empty)
                SaveAs(FileName);
            else
                Save();
             */
        }

        private void OpenStripMenuItem_Click(object sender, EventArgs e)
        {
            Open();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PathUtility.RestoreCurrentDirectory(Locality.CurrentProjectDir);
            saveProgramFile.InitialDirectory = Environment.CurrentDirectory;
            var res = saveProgramFile.ShowDialog();

            if (res != DialogResult.OK)
                return;

            SaveAs(saveProgramFile.FileName);
        }

        private void CommandListsForm_Load(object sender, EventArgs e)
        {
            InitializeVisualization();
        }

        private void OnVisualizationTick(object sender, EventArgs e)
        {
            VisualManager.RenderFrame();
        }

        private void OnTick(object sender, EventArgs e)
        {
            modellingSupervisor.OnPhisicModelling();
        }

        private void CommandListsForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            OnCommandListsUnloaded();
            compilationForm.Close();
            compilationForm = null;
            loggingManagement.Dispose();
        }

        private void ExitStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        #endregion

        #region Save/Load

        private void AskSave()
        {
            var res = MessageBox.Show("Сохранить программу '" + Path.GetFileNameWithoutExtension(FileName) + "' перед закрытием?", "Продолжить?",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            switch (res)
            {
                case DialogResult.No:
                    break;
                case DialogResult.Yes:
                    Save();
                    break;
            }
        }

        private void New()
        {
            AskSave();
            FileName = string.Empty;
            //this.Text = "Списки команд - [" + FileName + "]";           
            commandListsControl.ClearProgram();
            menuStrip1.Focus();
        }

        /// <summary>
        /// При выгрузке программы
        /// </summary>
        private void OnCommandListsUnloaded()
        {
            var ocl = ecoSpace.Ocl;

            Application.RemoveMessageFilter(keyFilter);

            var allcoms = ocl.Evaluate("Command.allInstances").GetAsIList<Command>();
            foreach (var com in allcoms)
                com.AsIObject().Delete();

            var allcomlists = ocl.Evaluate("CommandList.allInstances").GetAsIList<CommandList>();
            foreach (var comlist in allcomlists)
                comlist.AsIObject().Delete();
        }


        /// <summary>
        /// Загрузить программу из файла
        /// </summary>
        /// <param name="fileName">путь до файла</param>
        public void LoadProgram(string fileName)
        {
            //OnProgramUnloaded();
            FileName = fileName;
            //this.Text = "Списки команд - [" + FileName + "]";
            commandListsControl.LoadProgramFromFile(FileName);
        }

        private void Open()
        {
            AskSave();

            PathUtility.RestoreCurrentDirectory(Locality.CurrentProjectDir);
            openProgramDialog.InitialDirectory = Environment.CurrentDirectory;
            var res = openProgramDialog.ShowDialog();

            if (res == DialogResult.OK)
            {
                LoadProgram(openProgramDialog.FileName);
            }
        }

        /// <summary>
        /// Сохранить текущую открытую программу
        /// </summary>
        public void Save()
        {
            if (Path.GetFileNameWithoutExtension(FileName) == "")
            {
                PathUtility.RestoreCurrentDirectory(Locality.CurrentProjectDir);
                saveProgramFile.InitialDirectory = Environment.CurrentDirectory;
                var result = saveProgramFile.ShowDialog();
                if (result == DialogResult.OK)
                    SaveAs(saveProgramFile.FileName);
            }
            else SaveAs(FileName);
        }

        private void SaveAs(string path)
        {
            FileName = path;
            commandListsControl.SaveProgramToFile(FileName);
        }

        /// <summary>
        /// Закрыть окно CommandListsForm, почистви все за собой или сохранив несохраненное
        /// </summary>
        public void Exit()
        {
            //CloseQuery();
            OnStop();
            Application.RemoveMessageFilter(keyFilter);
            //DeInitializeConnections();
            commandListsControl.OnExit();
            Close();
        }

        /// <summary>
        /// Корректное закрытие
        /// </summary>
        public void CloseQuery()
        {
            AskSave();
            OnCommandListsUnloaded();
        }

        #endregion

        /// <summary>
        /// Настройки формы и компонентов для разных режимов
        /// </summary>
        private class FormSetting
        {
            public string ModeStripText { get; set; }
            public bool IsModellingCollapsed { get; set; }
        }

        private void StopStripMenuItem_Click(object sender, EventArgs e)
        {
            OnStop();
            PlayPauseAllToolStripMenuItem.Image = playPauseImages[0];
            PlayPauseAllToolStripMenuItem.Text = "Запустить";
        }

    }
}
